package divestoclimb.checklist;

import divestoclimb.checklist.data.Check;
import divestoclimb.checklist.data.Checklist;
import divestoclimb.checklist.data.Item;
import divestoclimb.checklist.data.ItemList;
import divestoclimb.checklist.storage.DbAdapter;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class FillChecklist extends ListActivity {

	public static final int STATE_TOGGLE = 99;

	private DbAdapter mDbHelper;
	private ItemList mItemList;
	private Long mChecklistId;
	private boolean mInitialized = false;
	
	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);

		Bundle params = icicle != null? icicle: getIntent().getExtras();

		mChecklistId = params.getLong(DbAdapter.KEY_CHECKLIST_ID);

		ListView lv = getListView();
		lv.setOnCreateContextMenuListener(this);
		lv.setItemsCanFocus(false);

		mDbHelper = new DbAdapter(this);
		mDbHelper.open();
		
		mItemList = new ItemList(DbAdapter.ITEM_CONTAINER_CHECKLIST, mChecklistId, mDbHelper);
		Cursor c = mItemList.getCursor();
		startManagingCursor(c);
		// Open the checklist, and make sure the start date has been set
		Checklist list = mDbHelper.fetchChecklist(mChecklistId);
		list.setStartDate();
		list.save(mDbHelper);

		// Build the list adapter
		final String from[] = new String[] {
			DbAdapter.KEY_CHECKLISTITEM_STATE,
			DbAdapter.KEY_CHECKLISTITEM_STATE,
			DbAdapter.KEY_ITEM_TEXT,
			DbAdapter.KEY_CHECKLISTITEM_WHENCHANGED
		};
		final int to[] = new int[] {
			R.id.checkbox,
			R.id.overlay,
			R.id.text,
			R.id.changedate
		};
		final int types[] = new int[] {
			ItemCursorAdapter.VIEW_TYPE_DEFAULT,
			ItemCursorAdapter.VIEW_TYPE_DEFAULT,
			ItemCursorAdapter.VIEW_TYPE_DEFAULT,
			ItemCursorAdapter.VIEW_TYPE_DATE
		};
		ItemCursorAdapter adapter = new ItemCursorAdapter((Context)this,
			R.layout.check, R.layout.note, c, DbAdapter.getDateFormatGMT(),
			from, to, types, DbAdapter.KEY_ITEM_TYPE, false);
		setListAdapter(adapter);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		if(! mInitialized) {
			mInitialized = true;
		} else {
			((CursorAdapter)getListView().getAdapter()).getCursor().requery();
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putLong(DbAdapter.KEY_CHECKLIST_ID, mChecklistId);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.checklist_fill, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()) {
		case R.id.info:
			Intent i = new Intent(this, EditChecklist.class);
			i.putExtra(DbAdapter.KEY_CHECKLIST_ID, mChecklistId);
			startActivityForResult(i, 0);
			break;
		}
		return super.onOptionsItemSelected(item);
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.checklist_fill_context, menu);

		// This menu has both Skip and Unskip options by default. Remove whichever
		// ones do not apply.
		Cursor item = (Cursor)getListView().getItemAtPosition(((AdapterView.AdapterContextMenuInfo)menuInfo).position);
		switch(item.getInt(item.getColumnIndexOrThrow(DbAdapter.KEY_CHECKLISTITEM_STATE))) {
		case Check.STATE_CHECKED:
			menu.removeItem(R.id.complete);
			menu.removeItem(R.id.skip);
		case Check.STATE_BLANK:
			menu.removeItem(R.id.unskip);
			break;
		case Check.STATE_SKIPPED:
			menu.removeItem(R.id.skip);
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		switch(item.getItemId()) {
		case R.id.complete:
			setState(info.position, Check.STATE_CHECKED);
			break;
		case R.id.skip:
			setState(info.position, Check.STATE_SKIPPED);
			break;
		case R.id.unskip:
			setState(info.position, Check.STATE_BLANK);
			break;
		case R.id.addnote:
			addNoteBelow(info.position);
		}

		return super.onContextItemSelected(item);
	}
	
	/**
	 * Change the state of a Check in the list
	 * @param position The position in the list of this Check
	 * @param state The new state to give the Check, as defined by the constants
	 * in Check or STATE_TOGGLE to toggle between CHECKED and BLANK.
	 */
	protected void setState(int position, int state) {
		Cursor c = (Cursor)getListView().getItemAtPosition(position);
		Item ch = mDbHelper.fetchChecklistItem(c.getLong(c.getColumnIndexOrThrow(DbAdapter.KEY_ITEM_ID)));
		if(ch instanceof Check) {
			int new_state = state;
			if(state == STATE_TOGGLE) {
				if(((Check)ch).getState() != Check.STATE_CHECKED) {
					new_state = Check.STATE_CHECKED;
				} else {
					new_state = Check.STATE_BLANK;
				}
			}
			((Check)ch).setState(new_state);
			((Check)ch).save(mDbHelper);
			mItemList.getCursor().requery();
		}
	}
	
	protected void addNoteBelow(int position) {
		Long selected_item;
		ListView lv = getListView();
		// The EditItem activity is expecting to be told which item to place this
		// note *above*. This is fine except for the case where we want the note
		// at the end of the list. We handle that case here.
		if(position + 1 < lv.getCount()) {
			Cursor c = (Cursor) lv.getItemAtPosition(position + 1);
			selected_item=c.getLong(c.getColumnIndexOrThrow(DbAdapter.KEY_ITEM_ID));
		} else {
			// Put this note at the end of the list
			selected_item=0L;
		}

		Intent i = new Intent(this, EditItem.class)
			.putExtra("containertype", DbAdapter.ITEM_CONTAINER_CHECKLIST)
			.putExtra("containerid", mChecklistId)
			.putExtra("action", EditItem.ACTION_NEW)
			.putExtra(DbAdapter.KEY_ITEM_TYPE, DbAdapter.ITEM_TYPE_NOTE)
			.putExtra(DbAdapter.KEY_ITEM_ID, selected_item);
		startActivityForResult(i, 0);
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		setState(position, STATE_TOGGLE);
	}
}